package com.tyqx.hashchainbiz.controller.config;

import com.tyqx.hashchainbiz.service.impl.JwtUserDetailsService;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUserDetailsService jwtUserDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        response.setHeader("Access-Control-Allow-Origin", "*");
//        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
//        response.setHeader("Access-Control-Max-Age", "3600");
//        response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token");
//        response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
//        if ("OPTIONS".equals(request.getMethod())) {
//            response.setStatus(HttpServletResponse.SC_OK);
//        } else {
//            filterChain.doFilter(request, response);
//        }
//    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        // pre-flight request
        if ("OPTIONS".equals(request.getMethod())) {//这里通过判断请求的方法，判断此次是否是预检请求，如果是，立即返回一个204状态吗，标示，允许跨域；预检后，正式请求，这个方法参数就是我们设置的post了
            response.setStatus(HttpServletResponse.SC_OK); //HttpStatus.SC_NO_CONTENT = 204
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS, DELETE");//当判定为预检请求后，设定允许请求的方法
            response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, Authorization"); //当判定为预检请求后，设定允许请求的头部类型
            response.addHeader("Access-Control-Max-Age", "1");
            chain.doFilter(request, response);
            return;
        }

        // filter
        final String requestURI = request.getRequestURI();
        if (requestURI.contains("/authenticate")|| requestURI.contains("/registerTrackUser")
                ||requestURI.contains("/test/insertHashValueExcelFile")||requestURI.contains("/test/verifyHashValue")
                ||requestURI.contains("/test/verifyDataExcelFile")||requestURI.contains("/yinyue/insertHashValueYinyue")
                ||requestURI.contains("yinyue/verifyDataYinyue")||requestURI.contains("/wx/userInfo/")
                ||requestURI.contains("/wx/company/")||requestURI.contains("/wx/sendFile/")||requestURI.contains("/sendFileToWxCompany/")
                ||requestURI.contains("/image/")||requestURI.contains("/wx/saveFile/")
                ||requestURI.contains("/wx/fileAuth")||requestURI.contains("/wx/blockChain")||requestURI.contains("/wx/")) {
            chain.doFilter(request, response);
        } else {
//            String body = JsonUtil.getBody(request);
//            body = body.replaceAll("\t","");
//            body = body.replaceAll("\n","");
//            body = body.replaceAll("\r","");
//            JsonObject bodyJson = new JsonParser().parse(body).getAsJsonObject();
//            String userName = bodyJson.get("userName").getAsString();
            String jwtToken = request.getHeader("Authorization");
            String userName = "";

            if (jwtToken != null) {
                try {
                    userName = jwtTokenUtil.getUsernameFromToken(jwtToken);
                } catch (IllegalArgumentException e) {
                    System.out.println("Unable to get JWT Token");
                } catch (ExpiredJwtException e) {
                    System.out.println("JWT Token has expired");
                    userName=e.getClaims().getSubject();
                }
            } else {
                logger.warn("JWT Token does not  String");
            }

            if (userName != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(userName);
                Date exp = jwtTokenUtil.getExpirationDateFromToken(jwtToken);
                if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {

                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                            userDetails, null, userDetails.getAuthorities());
                    usernamePasswordAuthenticationToken
                            .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }
            }
            chain.doFilter(request, response);
        }
    }

}